package com.xq.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xq.shop.config.FileConfig;
import com.xq.shop.config.Redis;
import com.xq.shop.dao.domain.entity.MyFile;
import com.xq.shop.dao.domain.entity.WebUser;
import com.xq.shop.dao.mapper.WebUserMapper;
import com.xq.shop.dto.IntegerDto;
import com.xq.shop.dto.QueryDto;
import com.xq.shop.dto.RegisterDto;
import com.xq.shop.dto.StringDto;
import com.xq.shop.service.IFileService;
import com.xq.shop.service.IWebUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xq.shop.utils.MyConstants;
import com.xq.shop.utils.SendEmailUtil;
import com.xq.shop.vo.UserVo;
import com.xq.shop.vo.WebUserVo;
import enums.DataStatus;
import exception.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import utils.BasePage;
import utils.PasswordUtil;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * <p>
 * 网页用户表 服务实现类
 * </p>
 *
 * @author gaoxiaojin
 * @since 2024-07-18
 */
@Service
public class WebUserServiceImpl extends ServiceImpl<WebUserMapper, WebUser> implements IWebUserService {

    @Resource
    private Redis redis;
    @Resource
    private FileConfig fileConfig;
    private final IFileService fileService;

    @Autowired
    public WebUserServiceImpl(IFileService fileService) {
        this.fileService = fileService;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(RegisterDto dto) {

        if (!redis.exists(dto.getCode())) {
            throw new BusinessException("code expire", "验证码失效，请重新获取");
        }
        String code = (String) redis.get(dto.getUsername());
        if (!code.equals(dto.getCode())) {
            throw new BusinessException("code error", "验证码错误");
        }
        String uuid = initId();
        WebUser webUser = new WebUser();
        BeanUtils.copyProperties(dto, webUser);
        webUser.setUuid(uuid);
        webUser.setPassword(PasswordUtil.enPawKey(dto.getPassword(), MyConstants.KEY1, MyConstants.KEY2, MyConstants.KEY3));
        save(webUser);
    }

    private String initId() {
        String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 10);
        LambdaQueryWrapper<WebUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(WebUser::getUuid, uuid);
        WebUser webUser = getOne(wrapper);
        if (Objects.nonNull(webUser)) {
            return initId();
        }
        return uuid;
    }

    @Override
    public void sendEmailCode(StringDto dto) {
        String code = SendEmailUtil.generateVerificationCode();
        // 发送验证码到邮箱
        SendEmailUtil.senEmail(dto.getValue(), code);
        redis.set(dto.getValue(), code, 120L);
    }

    @Override
    public BasePage<WebUserVo> pageUser(QueryDto dto, UserVo userVo) {
        LambdaQueryWrapper<WebUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WebUser::getStatus, DataStatus.NORMAL.getCode());
        if (Objects.nonNull(dto.getContent())) {
            queryWrapper.and(j -> j.like(WebUser::getNickname, dto.getContent())
                    .or().like(WebUser::getUsername, dto.getContent())
            );
        }
        queryWrapper.orderByDesc(WebUser::getId);
        IPage<WebUser> iPage = page(new Page<>(dto.getPage(), dto.getLimit()), queryWrapper);
        List<WebUser> webUserList = iPage.getRecords();
        if (webUserList.isEmpty()) {
            return new BasePage<WebUserVo>().initPage(dto.getPage(), dto.getLimit(), 0, 0, new ArrayList<>());
        }
        return new BasePage<WebUserVo>().initPage(dto.getPage(), dto.getLimit(), iPage.getTotal(), iPage.getPages(), beanToVo(webUserList));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeMark(IntegerDto dto) {
        WebUser webUser = getById(dto.getValue());
        if (Objects.nonNull(webUser)) {
            webUser.setMark(webUser.getMark() == 1 ? 2 : 1);
        }
        updateById(webUser);
    }

    private List<WebUserVo> beanToVo(List<WebUser> webUserList) {

        List<WebUserVo> voList = new ArrayList<>();
        webUserList.forEach(c -> {
            WebUserVo vo = new WebUserVo();
            BeanUtils.copyProperties(c, vo);
            if (Objects.nonNull(c.getHeadImage())) {
                MyFile file = fileService.getById(c.getHeadImage());
                vo.setHeadImageUrl(fileConfig.montageUrl(file.getUrl()));
            }
            voList.add(vo);
        });
        return voList;
    }

}
